import json
import os
import threading
from datetime import datetime
import json
from typing import List

# 全局锁（每个 batchId 可以有自己的锁，更精细）
file_locks = {}

def get_lock_for_file(filepath):
    """获取对应文件的线程锁（懒加载）"""
    if filepath not in file_locks:
        file_locks[filepath] = threading.Lock()
    return file_locks[filepath]

def update_image_result_safe(batch_id, unique_id, result, status="success", error=None):
    """
    线程安全地更新 JSON 文件中的某张图片结果
    """
    filepath = r"E:\Workspace\ai-integration-center-new\ai-img-ocr-server\tmp\batch.json"

    # 获取该文件的独占锁
    lock = get_lock_for_file(filepath)
    with lock:
        # 1. 读取当前文件内容
        if not os.path.exists(filepath):
            raise FileNotFoundError(f"Task file {filepath} not found.")

        with open(filepath, 'r', encoding='utf-8') as f:
            try:
                data = json.load(f)
            except json.JSONDecodeError as e:
                raise ValueError(f"Invalid JSON in {filepath}: {e}")

        # 2. 查找并更新指定 unique_id 的图片
        updated = False
        for item in data["imageResults"]:
            if item["uniqueId"] == unique_id:
                item["status"] = status
                item["result"] = result if status == "success" else None
                item["error"] = error
                item["processedAt"] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')
                updated = True
                break

        if not updated:
            print(f"[Warning] uniqueId {unique_id} not found in batch {batch_id}")
            return

        # 3. 更新统计字段
        data["processedCount"] = sum(1 for img in data["imageResults"] if img["status"] != "pending")
        data["updatedAt"] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')

        # 判断整体状态
        total = len(data["imageResults"])
        success_count = sum(1 for img in data["imageResults"] if img["status"] == "success")
        failed_count = sum(1 for img in data["imageResults"] if img["status"] == "failed")

        if success_count == total:
            data["status"] = "completed"
        elif failed_count > 0:
            data["status"] = "failed"
        else:
            data["status"] = "processing"

        # 4. 安全写回（原子性覆盖）
        temp_filepath = filepath + ".tmp"
        with open(temp_filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        os.replace(temp_filepath, filepath)  # 原子性替换（Linux/macOS安全，Windows也基本安全）

    print(f"[Success] Updated {unique_id} in batch {batch_id}")


def json_lines_to_list(json_lines_str: str) -> List[dict]:
    """
    将多行 JSON Lines 格式的字符串转换为 Python 列表（JSON 数组）
    
    示例输入：
        {"a": 1}\n{"b": 2}
    
    返回：
        [{"a": 1}, {"b": 2}]
    """
    lines = json_lines_str.strip().splitlines()
    result = []
    
    for line_num, line in enumerate(lines, 1):
        line = line.strip()
        if not line:
            continue  # 跳过空行
        try:
            obj = json.loads(line).get("classfy_result",{})
            result.append(obj)
        except json.JSONDecodeError as e:
            print(f"第 {line_num} 行 JSON 解析失败：{line}")
            raise e
    
    return result